import java.io.Serializable;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.ejb.EJB;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import org.primefaces.model.chart.CartesianChartModel;
import org.primefaces.model.chart.ChartSeries;
import com.google.code.ptrends.Application.DAL.Parameters;
import com.google.code.ptrends.Application.DAL.TrendsServiceBean;
import com.google.code.ptrends.Application.DAL.entities.ItemEntity;
import com.google.code.ptrends.Application.DAL.entities.ItemParameterEntity;
import com.google.code.ptrends.Application.DAL.entities.PriceEntity;
import com.google.code.ptrends.Application.DAL.entities.SupplierEntity;

@ManagedBean(name = "trendsBean")
@ViewScoped
public class TrendsBean implements Serializable {

	private static final long serialVersionUID = 1L;

	@EJB
	TrendsServiceBean beanService;

	private List<String> suppliers;
	private String[] selectedSuppliers = new String[] {};
	private SupplierEntity selectedSupplier;
	private Date startDate, endDate;
	private String itemString = "";
	private Parameters params;
	private List<ItemEntity> items = new ArrayList<ItemEntity>();
	private ItemEntity selectedItem;

	private CartesianChartModel itemModel;
	private int progress;

	private void setDefaultModel() {
		itemModel = new CartesianChartModel();
		ChartSeries none = new ChartSeries();
		none.setLabel("none");
		double d = 0.000;
		none.set("0", d);
		itemModel.addSeries(none);
	}

	public TrendsBean() {
		setDefaultModel();
	}

	public void setSuppliers(List<String> suppliers) {
		this.suppliers = suppliers;
	}

	public List<String> getSuppliers() {
		loadData();
		return suppliers;
	}

	public void setSelectedSuppliers(String[] selectedSuppliers) {
		this.selectedSuppliers = selectedSuppliers == null ? null
				: selectedSuppliers.clone();
	}

	public String[] getSelectedSuppliers() {
		String[] copy = new String[] {};
		if (this.selectedSuppliers != null) {
			copy = new String[this.selectedSuppliers.length];
			for (int i = 0; i < this.selectedSuppliers.length; i++) {
				copy[i] = new String(this.selectedSuppliers[i]);
			}
		}
		return copy;
	}

	public void setSelectedSupplier(SupplierEntity selectedSupplier) {
		this.selectedSupplier = selectedSupplier;
	}

	public SupplierEntity getSelectedSupplier() {
		return selectedSupplier;
	}

	private void loadData() {
		if (this.suppliers == null)
			this.suppliers = beanService.getAllSuppliers();
	}

	public void setStartDate(Date startDate) {
		this.startDate = startDate == null ? null : new Date(
				startDate.getTime());
	}

	public Date getStartDate() {
		Date cloned = null;
		if (startDate != null) {
			cloned = new Date(startDate.getTime());
		}
		return cloned;
	}

	public void setEndDate(Date endDate) {
		this.endDate = endDate == null ? null : new Date(endDate.getTime());
	}

	public Date getEndDate() {
		Date cloned = null;
		if (endDate != null) {
			cloned = new Date(endDate.getTime());
		}
		return cloned;
	}

	public void setItemString(String itemString) {
		this.itemString = itemString;
	}

	public String getItemString() {
		if (selectedItem != null) {
			StringBuilder sb = new StringBuilder();
			sb.append(selectedItem.getManufacturer().getName() + ", ");
			sb.append(selectedItem.getModel() + ", ");
			ItemParameterEntity[] p = selectedItem.getParameters()
					.toArray(
							new ItemParameterEntity[selectedItem
									.getParameters().size()]);
			for (int i = 0; i < p.length; i++) {
				sb.append(p[i].getValue());
				if (i != p.length - 1)
					sb.append(" / ");
			}
			itemString = sb.toString();
		}
		return itemString;
	}

	public void setParams(Parameters params) {
		this.params = params;
	}

	public Parameters getParams() {
		if (params == null)
			params = new Parameters();
		return params;
	}

	public void search(ActionEvent actionEvent) {
		if (progress != 0)
			progress = 0;
		this.progress = 20;
		items = beanService.getAllItemsByParameters(this.params);
		this.progress = 100;
	}

	public void setItems(List<ItemEntity> items) {
		this.items = items;
	}

	public List<ItemEntity> getItems() {
		return items;
	}

	public void setSelectedItem(ItemEntity selectedItem) {
		this.selectedItem = selectedItem;
	}

	public ItemEntity getSelectedItem() {
		return selectedItem;
	}

	public void setItemModel(CartesianChartModel itemModel) {
		this.itemModel = itemModel;
	}

	public CartesianChartModel getItemModel() {
		return itemModel;
	}

	private void updateChartData() {
		if (this.startDate == null || this.endDate == null) {
			FacesContext.getCurrentInstance().addMessage(null,
					new FacesMessage("Please select two dates"));
			return;
		}
		if (selectedSuppliers == null || selectedSuppliers.length == 0
				|| selectedItem == null) {
			FacesContext.getCurrentInstance().addMessage(null,
					new FacesMessage("Please select supplier and item"));
			return;
		}
		List<List<PriceEntity>> items = new ArrayList<List<PriceEntity>>();
		SimpleDateFormat dateformat = new SimpleDateFormat(
				"dd/MM/yy hh:mm");
		for (String str : selectedSuppliers) {
			items.add(beanService.getItemPrices(this.selectedItem.getId(), str,
					new Date(this.startDate.getTime()),
					new Date(this.endDate.getTime())));
		}
		List<ChartSeries> chartSeries = new ArrayList<ChartSeries>();
		for (List<PriceEntity> prices : items) {
			if (prices != null && prices.size() != 0) {
				ChartSeries serie = new ChartSeries();
				serie.setLabel(prices.get(0).getSupplier().getName());
				for (PriceEntity price : prices) {
					StringBuilder sb = new StringBuilder(
							dateformat.format(price.getPriceDate()));
					serie.set(sb.toString(),
							Double.parseDouble(price.getPrice()));
				}
				chartSeries.add(serie);
			}
		}
		if (chartSeries.size() != 0) {
			this.itemModel = new CartesianChartModel();
			for (ChartSeries serie : chartSeries)
				this.itemModel.addSeries(serie);
		} else {
			setDefaultModel();
			FacesContext.getCurrentInstance().addMessage(null,
					new FacesMessage("No results for with item"));
		}
	}

	public void loadChart(ActionEvent actionEvent) {
		updateChartData();
	}

	public void onComplete() {
		String msg = "No results";
		if (this.items != null && this.items.size() != 0)
			msg = "Load compleate";
		FacesContext.getCurrentInstance().addMessage(null,
				new FacesMessage(msg));
	}

	public void setProgress(Integer progress) {
		this.progress = progress;
	}

	public Integer getProgress() {
		return progress;
	}

}
